package com.ck.core.util;

import com.alibaba.fastjson.JSONObject;
import com.ck.core.constant.CharsetConstant;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpStatus;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * rest请求工具类
 */
public class RestClientUtils {

	public static final String SYSTEM_CHARSET_GBK ="GBK";

	private CloseableHttpClient httpclient = null;
	private Map<String, Object> param = new HashMap<String, Object>();
	private String targetUrl = null;

	private RestClientUtils(){}

	public static RestClientUtils newClient(){
		RestClientUtils restClient = new RestClientUtils();
		restClient.httpclient = HttpClientBuilder.create().build();
		return restClient;
	}

	public RestClientUtils target(String targetUrl){
		this.targetUrl = targetUrl;
		return this;
	}

	public RestClientUtils param(String key, Object value){
		param.put(key, value);
		return this;
	}

	/**
	 * @param remoteUrl 远程url
	 * @param paramMap 需要传递的参数
	 * args
	 * */
	public static String post(String remoteUrl, Map<String, Object> paramMap, int ... args) {
		return post(remoteUrl, paramMap, CharsetConstant.UTF8);
	}

	/**
	 * post提交，支持String值、String[]值
	 * @param remoteUrl 访问地址
	 * @param paramMap  参数Map
	 * @param responseCharset   字符集
	 * @return  String
	 */
	public static String post(String remoteUrl, Map<String, Object> paramMap, String responseCharset) {
		try {
			//构建post
			HttpPost httpPost = new HttpPost(new URL(remoteUrl).toURI());

			//构建params
			buildParams(httpPost,paramMap,responseCharset);

			//执行post
			CloseableHttpClient httpclient = HttpClientBuilder.create().build();
			HttpResponse response = httpclient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) {
				throw new RuntimeException("HTTP request Exception");
			}
			return EntityUtils.toString(response.getEntity(), responseCharset);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 构建header
	 * @param httpPost
	 * @param headerMap
	 */
	private static void buildHeaders(HttpPost httpPost,Map<String, String> headerMap) {
		if (headerMap != null && headerMap.size() > 0) {
			for (String key : headerMap.keySet()) {
				httpPost.setHeader(key,headerMap.get(key));
			}
		}
	}

	/**
	 * 构建params
	 * @param httpPost
	 * @param paramMap
	 * @param responseCharset
	 * @throws UnsupportedEncodingException
	 */
	private static void buildParams(HttpPost httpPost,Map<String, Object> paramMap,String responseCharset) throws UnsupportedEncodingException {
		//post参数
		if (paramMap != null && paramMap.size() > 0) {
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			for (String key : paramMap.keySet()) {
				Object value = paramMap.get(key);
				if (value instanceof Object[]) {
					//数组值
					Object[] texts = (Object[])value;
					for (Object text : texts) {
						params.add(new BasicNameValuePair(key, text.toString()));
					}
				} else {
					String text = value.toString();
					params.add(new BasicNameValuePair(key, text));
				}
			}
			httpPost.setEntity(new UrlEncodedFormEntity(params, responseCharset));
		}
	}

	/**
	 * 构建一个以json格式请求的post,可自定义请求头内容
	 * @param remoteUrl  目标地址
	 * @param jsonObject  参数（jsonObj）
	 * @param headerMap  自定义请求头内容
	 * @return
	 */
	public static String postWithJson(String remoteUrl, JSONObject jsonObject, Map<String, String> headerMap) {
		HttpPost httpPost = null;
		try {
			//构建post
			httpPost = new HttpPost(new URL(remoteUrl).toURI());
			// post 构建自定义header内容
			buildHeaders(httpPost,headerMap);

			// 指定json格式
			httpPost.setHeader("Content-type", "application/json; charset=utf-8");

			// post 构建消息实体
			StringEntity entity = new StringEntity(jsonObject.toString(), CharsetConstant.UTF8);
			entity.setContentEncoding(CharsetConstant.UTF8);
			// 发送Json格式的数据请求
			entity.setContentType("application/json");
			httpPost.setEntity(entity);

			//执行post
			CloseableHttpClient httpclient = HttpClientBuilder.create().build();
			HttpResponse response = httpclient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != org.apache.http.HttpStatus.SC_OK) {
				throw new RuntimeException("HTTP request Exception; StatusCode: " + response.getStatusLine().getClass());
			}
			return EntityUtils.toString(response.getEntity(), CharsetConstant.UTF8);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if(httpPost != null){
				httpPost.releaseConnection();
			}
		}
	}

	/**
	 * 构建一个以json格式请求的post,可自定义请求头内容
	 * @param remoteUrl  目标地址
	 * @param paramMap  参数（paramMap）
	 * @param headerMap  自定义请求头内容
	 * @return
	 */
	public static String postWithForm(String remoteUrl, Map<String, Object> paramMap, Map<String, String> headerMap) {
		HttpPost httpPost = null;
		try {
			//构建post
			httpPost = new HttpPost(new URL(remoteUrl).toURI());

			// post 构建自定义header内容
			buildHeaders(httpPost,headerMap);

			// 构建参数
			buildParams(httpPost,paramMap,CharsetConstant.UTF8);

			CloseableHttpClient httpclient = HttpClientBuilder.create().build();
			//执行post
			HttpResponse response = httpclient.execute(httpPost);
			if (response.getStatusLine().getStatusCode() != org.apache.http.HttpStatus.SC_OK) {
				throw new RuntimeException("HTTP request Exception; StatusCode: " + response.getStatusLine().getClass());
			}
			return EntityUtils.toString(response.getEntity(), CharsetConstant.UTF8);
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if(httpPost != null){
				httpPost.releaseConnection();
			}
		}
	}
}